home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / MODCTRL.I < prev    next >
Encoding:
Text File  |  1994-06-24  |  15.1 KB  |  3 lines

  1. ⓪ IMPLEMENTATION MODULE ModCtrl;⓪ (*$Y+,P-,V+,C-,R-*)⓪ ⓪ (* V#115⓪"15.01.88  TT  GetModName mit Prozedurnamen⓪"01.04.88  TT  findName fängt Bus/Addr-Error ab.⓪"02.04.88  TT  InstallModule: Bei unterstem Level wird Basepage, Environment⓪0und aller allozierter Speicher (ALLOCATE + SysAlloc) resident⓪0gemacht.⓪"10.06.88  TT  GetModName: IF-Abfrage vor Prozedurnamen-Ermitteln korrigiert.⓪"27.08.88  TT  GetModName/findName zerstört nicht mehr Addr-Error-Exc-Vektor⓪0und außerdem wird Stack bei Bus/Addr-Error nun auch bei 68020⓪0richtig wiederhergestellt.⓪"30.09.88  TT  KeepAll wieder aus InstallModule entfernt;⓪0ModList und eigenes CODE-Segment/Basepage werden bei DeInstall⓪0entfert, wenn Prg resident war.⓪"09.12.88  TT  Residentmachen/Freigabe von gelinktem Modul wird über 'linked'-⓪0Flag in 'state' statt über ModLevel erkannt.⓪"10.12.88  TT  ReleaseModule holt sich eigene Basepage-Adr via 'GetPDB' statt⓪0aus 'BaseProcess'.⓪"04.07.89  TT  Install/ReleaseModule: Residentmachen bei gelinkten Prgs⓪0erfolgt erst bei deren Prozeßende.⓪"14.07.89  TT  ReleaseModule: Freigabe der base page/tpa geschieht direkt⓪0über gemdos.mfree, da sonst Probleme bei residenten Prgs⓪0auftritt.⓪"26.07.89  TT  CatchProcessTerm wird nicht doppelt installiert, wenn⓪0InstallModule doppelt aufgerufen wird.⓪"09.10.89  TT  GetModName bestimmt Proc-Name nun wieder korrekt;⓪0falls sourceName bei GetSourceName nicht paßt, wird Pfad⓪0abgeschnitten⓪"13.06.90  TT  EnterSupervisorMode-Aufrufe raus⓪"17.07.90  TT  QueryImports neu⓪"26.09.90  TT  GetProcAddr meldet nicht schon Erfolg, wenn nur der zu kurz⓪0angegebene Name paßt.⓪"14.02.92  TT  GEMDOS.Super-Aufrufe statt Supexec wg. MinT.⓪"23.02.92  TT  Anpassung an neues "CreateBasePage".⓪"24.06.94  TT  Neben FullStorBaseAccess wird nun auch ExtendedMemoryAccess⓪0beim Residentinstallieren geprüft, damit man dieses Flag auch⓪0noch im Hauptprg. auf FALSE setzen kann. Falls Modul resident⓪0installiert wird, wird PtermRes erst ganz am Ende aller⓪0Termination-Handler aufgerufen (bisher passierte dies eher⓪0gleich am Anfang und so wurden evtl. die restlichen Handler⓪0zu spät aufgerufen). Falls Ptermres() zum Installieren benutzt⓪0werden muß, wird dies nicht mehr hier sondern in MOSCtrl⓪0erledigt.⓪ *)⓪ ⓪ FROM SYSTEM IMPORT ASSEMBLER, ADR, WORD, ADDRESS, DEREF, TSIZE, LONGWORD;⓪ ⓪ FROM ModBase IMPORT FindRef, ModLst, CallEnvelopes, ModRef, ModStates,⓪0MarkState, ModState, PtrModHeader, ModHeader,⓪0CreateBasePage, ExecProcess, ModLoaded, ModStr;⓪ ⓪ FROM StorBase IMPORT Keep, FullStorBaseAccess;⓪ ⓪ FROM MOSCtrl IMPORT BaseResident, CallRemoveProcs, GetPDB, PDB,⓪(TermEntry, ModLevel, PtrPDB;⓪ ⓪ FROM MOSSupport IMPORT ToSuper, ToUser;⓪ ⓪ FROM SysTypes IMPORT PtrBP;⓪ ⓪ FROM MOSGlobals IMPORT IllegalState, MemArea;⓪ ⓪ FROM PrgCtrl IMPORT TermProcess, TermCarrier, CatchProcessTerm;⓪ ⓪ FROM Lists IMPORT ResetList, PrevEntry, RemoveEntry, DeleteList, List,⓪(NextEntry, LDir;⓪ ⓪ FROM FileNames IMPORT PathConc, SplitPath;⓪ ⓪ FROM Strings IMPORT Assign, Length, StrEqual, Upper, Delete, Split, Pos;⓪ ⓪ FROM MOSConfig IMPORT ExtendedMemoryAccess;⓪ ⓪ ⓪ VAR caught,ok,error:BOOLEAN;⓪$wsp: MemArea;⓪$tcarrier: TermCarrier;⓪$MakeResident, madeResident: BOOLEAN;⓪ ⓪ PROCEDURE findNameAddr (modhead,name:ADDRESS): ADDRESS;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; Format der Namen vor Procs:⓪(;   ... code ... RTS⓪(;   0-Byte auf gerade Adr.⓪(;   Name mit Null am Ende⓪(;   [0-Byte f. SYNC]⓪(;   Ptr auf vorige Proc hinter diesen Ptr⓪(;⓪(SUBQ.L  #4,A3⓪(SUBQ.L  #4,A7⓪(JSR     ToSuper⓪(⓪(LEA     err2(PC),A0⓪(MOVE.L  8,D0⓪(MOVE.L  A0,8            ; Bus error⓪(MOVE.L  12,D1⓪(MOVE.L  A0,12           ; Addr error⓪(⓪(MOVE.L  (A3),A2         ; rel⓪(MOVE.L  -(A3),A0        ; mod⓪(MOVE.L  ModHeader.body(A0),D1⓪%l: MOVE.L  D1,A1⓪(ADDA.L  A0,A1           ; A1 zeigt auf Proc-Beginn (hinter Namen)⓪(⓪(MOVEM.L D1/A1/A2,(A3)   ; D1/A1/A2 retten⓪(SUBQ.L  #6,A1⓪%m: TST.B   -(A1)⓪(BNE     m⓪(ADDQ.L  #1,A1           ; nun zeigt A1 auf Namen⓪(; vergleichen⓪%n: MOVE.B  (A1)+,D1⓪(BEQ     found⓪(CMPI.B  #'a',D1⓪(BCS     o⓪(CMPI.B  #'z',D1⓪(BHI     o⓪(SUBI.B  #32,D1⓪%o: CMP.B   (A2)+,D1⓪(BEQ     n⓪(MOVEM.L (A3),D1/A1/A2⓪(⓪(MOVE.L  -(A1),D1        ; Vorgänger-Proc⓪(BEQ     e               ; nicht gefunden ('rel' zu klein)⓪(BRA     l⓪%err2⓪(SUBA.W  #14,A7          ; Bus/Addr-Error, SSP korrigieren⓪(MOVEQ   #0,D1⓪(BRA     e⓪%found:⓪(TST.B   (A2)            ; auch Name im Code zuende?⓪(BNE     l               ; nein: weitersuchen⓪(MOVEM.L (A3),D1/A1/A2⓪%e: MOVE.L  D1,(A3)+⓪(⓪(MOVE.L  D0,8            ; Bus error⓪(MOVE.L  D1,12           ; Addr error⓪(⓪(JSR     ToUser⓪(ADDQ.L  #4,A7⓪$END⓪"END findNameAddr;⓪"(*$L=*)⓪ ⓪ PROCEDURE GetProcAddr (mname: ARRAY OF CHAR; VAR location: ADDRESS);⓪"VAR dummy, pname: ARRAY [0..39] OF CHAR; withPN, getBody, ok: BOOLEAN;⓪&code: ADDRESS; ref0: ModRef;⓪"BEGIN⓪$Upper (mname);⓪$withPN:= Pos ('.', mname, 0) > 0;⓪$IF withPN THEN⓪&Split (mname, Pos ('.', mname, 0), mname, pname, ok);⓪&Delete (pname, 0, 1, ok);⓪&IF pname[0]=0C THEN⓪(withPN:= FALSE⓪&ELSE⓪(getBody:= StrEqual (pname, mname);⓪&END⓪$END;⓪$location:= NIL;⓪$IF ModLoaded (mname, FALSE, dummy, ref0) THEN⓪&IF withPN THEN⓪(code:= ref0^.header;⓪(IF getBody THEN⓪*location:= code + ref0^.header^.body⓪(ELSIF procSym IN ref0^.state THEN⓪*location:= findNameAddr (code, ADR (pname));⓪*IF location # NIL THEN INC (location, LONGCARD(code)) END;⓪(END⓪&ELSE⓪(location:= ref0^.codeStart⓪&END⓪$END⓪"END GetProcAddr;⓪ ⓪ (*$H+*)⓪ PROCEDURE ProcQuery (REF modName: ARRAY OF CHAR;⓪9call   : ProcQueryProc;⓪5VAR ok     : BOOLEAN);⓪"VAR dummy: ModStr; ref0: ModRef; p, pa: ADDRESS; pn: LONGCARD;⓪"TYPE PL = POINTER TO LONGCARD;⓪'PC = POINTER TO CHAR;⓪'PS = POINTER TO ARRAY [0..39] OF CHAR;⓪"BEGIN⓪$ok:= FALSE;⓪$IF ModLoaded (modName, FALSE, dummy, ref0) THEN⓪&WITH ref0^ DO⓪(IF (procSym IN state) THEN⓪*(*  ... code ... RTS⓪.0-Byte auf gerade Adr.⓪.Name mit Null am Ende⓪.0-Byte f. SYNC]⓪.Ptr auf vorige Proc hinter diesen Ptr *)⓪*pn:= header^.body; (* Beim Body fängt die Kette rückw. an *)⓪*WHILE pn # 0 DO⓪,p:= ADDRESS(header) + pn; (* Proc-Adr. absolut *)⓪,pa:= p; (* Proc-Adr. merken *)⓪,DEC (p, 4); (* zum Ptr vor Name *)⓪,pn:= DEREF (PL(p));⓪,DEC (p, 3); (* zum Ende des Namens *)⓪,WHILE DEREF(PC(p)) # 0C DO DEC (p) END; (* zum Beginn d. Namens *)⓪,call (DEREF (PS(p+1)), pa)⓪*END;⓪*ok:= TRUE⓪(END;⓪&END; (* WITH *)⓪$END⓪"END ProcQuery;⓪ ⓪ PROCEDURE ModQuery ( call: ModQueryProc );⓪"VAR l:List; m: ModRef;⓪"BEGIN⓪$l:=ModLst;⓪$ResetList (l);⓪$LOOP⓪&m:= NextEntry (l);⓪&IF m = NIL THEN EXIT END;⓪&WITH m^ DO⓪(call ( codeName^, codeStart, codeLen, varRef, varLen,⓪/fileName (*PathConc (fileName, filePath)*),⓪/~(program IN state), loaded IN state,⓪/(installed IN state) OR (linked IN state) );⓪&END;⓪$END⓪"END ModQuery;⓪ ⓪ PROCEDURE QueryImports (REF client: ARRAY OF CHAR; call: ModQueryProc);⓪"VAR dummy: ModStr; ref0: ModRef; imp: POINTER TO ModRef;⓪"BEGIN⓪$IF ModLoaded (client, FALSE, dummy, ref0) THEN⓪&imp:= ADDRESS (ref0^.imports);⓪&IF imp # NIL (* existiert Importliste? *) THEN⓪(WHILE imp^ # NIL DO⓪*WITH imp^^ DO⓪,call (codeName^, codeStart, codeLen, varRef, varLen,⓪2fileName (*PathConc (fileName, filePath)*),⓪2~(program IN state), loaded IN state,⓪2(installed IN state) OR (linked IN state))⓪*END;⓪*INC (imp, 4)⓪(END⓪&END⓪$END⓪"END QueryImports;⓪ (*$H-*)⓪ ⓪ ⓪ PROCEDURE findName (modhead:ADDRESS;rel:LONGCARD): ADDRESS;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; Format der Namen vor Procs:⓪(;   ... code ... RTS⓪(;   0-Byte auf gerade Adr.⓪(;   Name mit Null am Ende⓪(;   [0-Byte f. SYNC]⓪(;   ^ auf vorige Proc hinter diesen ^ (rel. zu header!)⓪(;⓪(SUBQ.L  #4,A3⓪(SUBQ.L  #4,A7⓪(JSR     ToSuper⓪ ⓪(LEA     err2(PC),A0⓪(MOVE.L  8,-(A7)⓪(MOVE.L  A0,8            ; Bus error⓪(MOVE.L  12,-(A7)⓪(MOVE.L  A0,12           ; Addr error⓪(MOVE.L  A7,A2⓪ ⓪(MOVE.L  (A3),D0         ; rel⓪(MOVE.L  -(A3),A0        ; header⓪(ADD.L   ModHeader.codeStart(A0),D0⓪(MOVE.L  ModHeader.body(A0),D1⓪ ⓪%l: MOVE.L  D1,A1           ; rel. Proc-Beginn⓪(ADDA.L  A0,A1           ; abs. Proc-Beginn⓪(CMP.L   D1,D0⓪(BCC     found⓪(MOVE.L  -(A1),D1        ; Vorgänger-Proc⓪(BEQ     e               ; nicht gefunden ('rel' zu klein)⓪(BRA     l⓪%err2⓪(MOVE.L  A2,A7           ; Bus/Addr-Error, SSP korrigieren⓪(MOVEQ   #0,D1⓪(BRA     e⓪%found:⓪(SUBQ.L  #6,A1⓪%m: TST.B   -(A1)⓪(BNE     m⓪(ADDQ.L  #1,A1⓪(MOVE.L  A1,D1⓪%e: MOVE.L  D1,(A3)+⓪(⓪(MOVE.L  (A7)+,12        ; Addr error⓪(MOVE.L  (A7)+,8         ; Bus error⓪$⓪(JSR     ToUser⓪(ADDQ.L  #4,A7⓪$END⓪"END findName;⓪"(*$L=*)⓪ ⓪ PROCEDURE GetModName ( Ad          : Address;⓪7VAR modul   : ARRAY OF Char;⓪7VAR relAddr : LONGCARD;⓪7VAR procName: ARRAY OF CHAR );⓪"VAR i: ModRef; n: POINTER TO ARRAY [0..79] OF CHAR;⓪"BEGIN⓪$FindRef (ad,i);⓪$relAddr:= 0L;⓪$procName[0]:= 0C;⓪$IF i=NIL THEN⓪&modul[0]:= 0C;⓪$ELSE⓪&Assign (i^.codename^,modul,ok);⓪&relAddr:= ad - i^.codeStart;⓪&IF procSym IN i^.state THEN⓪(n:= findName (i^.header, relAddr);⓪(IF n # NIL THEN⓪*Assign (n^, procName, ok)⓪(END⓪&END;⓪&IF crunched IN i^.state THEN⓪(relAddr:= 0L (* wurde vorher noch gebraucht ! *)⓪&END⓪$END⓪"END GetModName;⓪ ⓪ ⓪ VAR dummy: ADDRESS;⓪ ⓪ PROCEDURE CatchProcessTermLast (VAR hdl: TermCarrier; call: Proc; wsp: MemArea);⓪"(*⓪#* Proc ganz ans Ende der Term-Liste, damit diese Routine als ALLERLETZTE⓪#* aufgerufen wird.⓪#* Zudem wird die Routine im untersten PDB, also dem des gelinkten Prozesses,⓪#* installiert.⓪#*)⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(CLR.L   -(A7)⓪(MOVE.L  A7,(A3)+⓪(MOVE.L  #dummy,(A3)+⓪(JSR     GetPDB⓪(MOVE.L  (A7)+,A0⓪(MOVE.L  A0,D0⓪(BEQ     noMod⓪(; untersten PDB finden⓪&findBottom:⓪(MOVE.L  PDB.prev(A0),D0⓪(BEQ     foundBottom⓪(MOVE.L  D0,A0⓪(BRA     findBottom⓪&foundBottom:⓪(; Ende der Term-Liste finden⓪&findEnd:⓪(MOVE.L  PDB.TermProcs(A0),D1⓪(BEQ     foundEnd⓪(MOVE.L  D1,A0⓪(BRA     findEnd⓪&foundEnd:⓪(MOVE.L  -(A3),D2⓪(MOVE.L  -(A3),A2⓪(MOVE.L  -(A3),D0⓪(MOVE.L  -(A3),A1⓪(MOVE.L  A1,PDB.TermProcs(A0)    ; pdb.TermProcs:= ADR (hdl)⓪(CLR.L   TermEntry.next(A1)      ; hdl.next:= NIL (end of list)⓪(MOVE.L  D0,TermEntry.call(A1)   ; hdl.call:= call⓪(MOVE.L  D2,TermEntry.wsp.length(A1)⓪(MOVE.L  A2,TermEntry.wsp.bottom(A1)⓪(RTS⓪&noMod:⓪(TRAP    #6⓪(DC.W    -14     ; Ill. call⓪(SUBA.W  #$10,A3⓪$END⓪"END CatchProcessTermLast;⓪"(*$L+*)⓪ ⓪ PROCEDURE termination;⓪"VAR p: PtrPDB; pr: ADDRESS; bp: PtrBP;⓪"BEGIN⓪$IF MakeResident & madeResident THEN⓪&madeResident:= TRUE;⓪&GetPDB (p,pr);⓪&bp:= p^.basePageAddr;⓪&Keep (bp);⓪&Keep (bp^.p_env)⓪$END⓪"END termination;⓪ ⓪ PROCEDURE InstallModule (removalInfo: PROC; wsp: MemArea);⓪"VAR i:ModRef; ad:Address; inst: BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪&MOVE.L  4(A5),ad(A6)       ; RTS-Adr. v.Stack⓪$END;⓪$FindRef (ad,i);⓪$inst:= FALSE;⓪$IF i=NIL THEN⓪&(* Ist wohl ein gelinktes, optimiertes Modul *)⓪&inst:= TRUE;⓪$ELSIF ~(installed IN i^.state) THEN⓪&Incl (i^.state,installed);⓪&i^.removeInfo:= removalInfo;⓪&i^.removeWsp:= wsp;⓪&IF linked IN i^.state THEN⓪(inst:= TRUE;⓪&END⓪$END;⓪$IF inst THEN⓪&(*⓪'* Das Residentmachen des eigenen Programmbereichs & basepage⓪'* erfolgt erst beim Prozeßende, falls dann MakeResident noch TRUE ist.⓪'*)⓪&IF NOT caught & FullStorBaseAccess () & ExtendedMemoryAccess THEN⓪(CatchProcessTermLast (tcarrier, termination, wsp);⓪(MakeResident:= TRUE;⓪(madeResident:= FALSE;⓪(caught:= TRUE⓪&ELSE⓪((*⓪)* Prg muß mit Ptermres() resident gemacht werden.⓪)* Das wird automatisch in MOSCtrl erledigt.⓪)*)⓪(BaseResident:= TRUE;⓪&END⓪$END⓪"END InstallModule;⓪ ⓪ ⓪ PROCEDURE Mfree (ad: ADDRESS);⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  -(A3),-(A7)⓪(MOVE.W  #$49,-(A7)⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪$END⓪"END Mfree;⓪"(*$L=*)⓪ ⓪ PROCEDURE ReleaseModule;⓪"VAR i:ModRef; ad:Address; p: PtrPDB; pr: ADDRESS; bp: PtrBP; deinst: BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪&MOVE.L  4(A5),ad(A6)       ; RTS-Adr. v.Stack⓪$END;⓪$FindRef (ad,i);⓪$deinst:= FALSE;⓪$IF i=NIL THEN⓪&(* Ist wohl ein gelinktes, optimiertes Modul *)⓪&deinst:= TRUE⓪$ELSIF installed IN i^.state THEN⓪&EXCL (i^.state,installed);⓪&IF (linked IN i^.state) THEN⓪(deinst:= TRUE;⓪&END⓪$END;⓪$IF deinst & (MakeResident OR BaseResident) THEN⓪&BaseResident:= FALSE;⓪&MakeResident:= FALSE;⓪&IF ModLevel = 0 THEN⓪((*⓪)* Nur eigene Freigabe, wenn DeInstall nicht noch vor Ende des⓪)* eigenen Prozesses, unter dem auch Installed wurde, aufgerufen⓪)* wird.⓪)*)⓪(CallRemoveProcs; (* Hierüber wird auch 'removal' in ModBase aufgerufen *)⓪((*⓪)* Auch der eigene Programmplatz wird freigegeben -> Vorsicht !⓪)*)⓪(IF madeResident THEN⓪*GetPDB (p, pr);⓪*bp:= p^.basePageAddr;⓪*Mfree (bp^.p_env);(* nicht DEALLOCATE verwenden, weil durch         *)⓪*Mfree (bp);       (* Removal-Aufrufe bereits Storage abgemeldet ist!*)⓪*(*⓪+* Hiernach muß das Programm selbst enden !⓪+*)⓪)END⓪&END;⓪$END⓪"END ReleaseModule;⓪ ⓪ ⓪ PROCEDURE FirstModuleStart ():Boolean;⓪"VAR i:ModRef; ad:Address;⓪"BEGIN⓪$ASSEMBLER⓪&MOVE.L  4(A5),ad(A6)       ; RTS-Adr. v.Stack⓪$END;⓪$FindRef (ad,i);⓪$IF i=NIL THEN⓪&(* Ist wohl ein gelinktes, optimiertes Modul *)⓪&RETURN TRUE⓪$ELSE⓪&RETURN (firstCall IN i^.state) OR (linked IN i^.state)⓪$END⓪"END FirstModuleStart;⓪ ⓪ ⓪ PROCEDURE GetOwnName (VAR codeName: ARRAY OF CHAR);⓪"VAR i:ModRef; ad:Address;⓪"BEGIN⓪$ASSEMBLER⓪&MOVE.L  4(A5),ad(A6)       ; RTS-Adr. v.Stack⓪$END;⓪$codename[0]:=0C;⓪$FindRef (ad,i);⓪$IF i=NIL THEN⓪&(* Ist wohl ein gelinktes, optimiertes Modul *)⓪&codeName[0]:= 0C⓪$ELSE⓪&Assign (i^.codeName^,codeName,ok)⓪$END⓪"END GetOwnName;⓪ ⓪ ⓪ PROCEDURE GetSourceName ( REF codeName  : ARRAY OF CHAR;⓪:VAR sourceName: ARRAY OF CHAR;⓪:VAR opts      : LONGWORD );⓪"VAR r:ModRef; mname:ModStr; path: ARRAY [0..127] OF CHAR;⓪&p: POINTER TO ModStr;⓪"BEGIN⓪$IF ModLoaded (codename,FALSE,mname,r) & ~(program IN r^.state) THEN⓪&p:= ADDRESS (r^.header) + r^.header^.sourceName;⓪&Assign (p^, sourceName, ok);⓪&IF ~ ok THEN⓪(SplitPath (p^, path, sourceName)⓪&END;⓪&opts:= r^.header^.options⓪$ELSE⓪&sourceName[0]:=0C;⓪&opts:= LONGWORD (0L)⓪$END⓪"END GetSourceName;⓪ ⓪ ⓪ PROCEDURE CallProcess (    pro      : PROC;⓪;workSpace: MemArea;⓪7VAR ok       : BOOLEAN;⓪7VAR exitCode : INTEGER );⓪ ⓪"VAR bp: PtrBP; termState: CARDINAL; noStr: CHAR;⓪"⓪"BEGIN (* CallProcess *)⓪$noStr:= 0C;⓪$ok:= CreateBasePage (bp, 0, ADR(noStr), LONGCARD(7));⓪$IF ok THEN⓪&WITH bp^ DO⓪(p_lowtpa:= workSpace.bottom;⓪(p_hitpa:= p_lowtpa + workSpace.length⓪&END;⓪&ExecProcess (bp, pro, ADR(noStr), LONGCARD(7), termState, exitCode);⓪&ok:= termState = 2;⓪&Mfree (bp^.p_env);⓪&Mfree (bp)⓪$END⓪"END CallProcess;⓪ ⓪ END ModCtrl.⓪ ə
  2. (* $FFEFFD49$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$00000002$FFFADB5A$00003A27$FFFADB5A$00002803$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5A$FFFADB5AÇ$00000002T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00002984$00002D40$00002D14$000029BE$000029AB$00003201$00003307$00003311$000030B6$00003086$000008E4$00000002$00000CBD$0000299F$00002993$00000CBDãÇâ*)
  3.